﻿namespace Digitalmes.Application.Common.Models;

/// <summary>
/// 数据处理结果
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class Result<T> : IResult<T>
{
    internal Result([MaybeNull] T value, string? message)
    {
        Value = value;
        Message = message;
    }

    [AllowNull]
    public T Value { get; }

    public string? Message { get; }
}

/// <summary>
/// 处理结果工厂。
/// </summary>
public static class Result
{
    /// <summary>
    /// 成功
    /// </summary>
    /// <returns></returns>
    public static IResult<bool> Success()
    {
        return new Result<bool>(true, null);
    }

    /// <summary>
    /// 失败
    /// </summary>
    /// <param name="error">错误原因</param>
    /// <returns></returns>
    public static IResult<bool> Failure(string? error = null)
    {
        return new Result<bool>(false, error);
    }

    /// <summary>
    /// 返回指定类型的结果。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">值</param>
    /// <param name="message">消息</param>
    /// <returns></returns>
    /// <remarks>
    /// 若 value 为 <see cref="Enum"/> 类型，当 message 为 null 时会采用对应的 <see cref="DescriptionAttribute"/> 特性值代替。
    /// </remarks>
    public static IResult<T> From<T>([MaybeNull] T value, string? message = null)
    {
        if (message == null && value is Enum @enum)
        {
            message = @enum.Description();
        }

        return new Result<T>(value, message);
    }
}
